﻿namespace NetFx.SMIL.Definitions
{
  using System;
  using System.Text;
  using System.Collections;
  using System.Collections.Generic;

  using System.Reflection;
  using System.Reflection.Emit;
  using System.Runtime.InteropServices;

  using System.Diagnostics;
  using System.Diagnostics.CodeAnalysis;
  using System.Diagnostics.SymbolStore;
  using System.Security;
  using System.Security.Permissions;

  using NetFx.MSIL;
  using NetFx.SMIL.References;

  public class LabelDef : ReflectDef
  {
    #region Statics
    public static string DefaultLabelName = ".label";

    public static LabelDef of(long address)
    {
      return new LabelDef(address);
    }
    public static LabelDef of(string name)
    {
      return new LabelDef(name);
    }
    public static LabelDef of(string name, long address)
    {
      return new LabelDef(name, address);
    }
    #endregion
    #region Fields
    protected long address;
    #endregion
    #region Properties
    public override DefType DefinitionType
    {
      get { return DefType.Label; }
    }
    public virtual long Address
    {
      get
      {
        return this.address;
      }
      set
      {
        this.address = value;
      }
    }
    #endregion
    #region Constructors
    public LabelDef(long address)
      : this(String.Empty,address)
    {
      this.name = this.OnNamingLabel(address);
    }
    public LabelDef(string name):this(name,0L)
    {

    }
    public LabelDef(string name, long address)
      : base(name)
    {
      this.address = address;
    }
    #endregion
    #region Methods
    public override string ToString()
    {
      return string.Format("{0} ({1:X8})", this.Name, this.Address);
    }
    protected override AnyGenerator OnCompleting(AnyGenerator generator)
    {
      if (generator is LabelGenerator)
      {
        ((LabelGenerator)generator).Name = this.name;
        ((LabelGenerator)generator).Address = this.address;
      }
      return base.OnCompleting(generator);
    }
    protected override AnyGenerator OnDefining(AnyGenerator container)
    {
      if (container is MethodGenerator)
      {
        return ((MethodGenerator)container).DefineLabel(this.name, this.address);
      }
      return base.OnDefining(container);
    }
    protected override ReflectDef OnReflecting(object source)
    {
      if (source is string)
      {
        this.name = source as string;
      }
      else if (source is long || source is long || source is int || source is uint)
      {
        this.name = this.OnNamingLabel(this.address = (long)source);

      }
      return base.OnReflecting(source);
    }
    protected virtual string OnNamingLabel(long address)
    {
      return string.Format("{0}_{1:X8}",DefaultLabelName , address);
    }

    #endregion
  }
}